package com.pai4j.common.util;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * JsonUtil类提供了JSON与Java对象之间的相互转换功能
 *
 * 序列化： 将Java对象转换为字节流（JSON字符串），方便后续的存储（保存在文件中）和传输（在网络间）
 * 反序列化：将字节流（JSON字符串）转换为Java对象
 *
 * @author: CYM-pai
 * @date: 2025/04/16 11:24
 **/


@Slf4j
public class JsonUtil {

    // ObjectMapper是Jackson库中用于JSON与Java对象转换的核心类
    private static ObjectMapper om = new ObjectMapper();

    // JsonFactory用于创建JsonParser和JsonGenerator实例
    private static JsonFactory factory = new JsonFactory();

    // 静态代码块用于配置ObjectMapper
    static {
        // 配置反序列化时忽略未知属性
        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 配置序列化时将日期作为时间戳输出
        om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
    }

    /**
     * 将JSON字符串转换为指定类型的Java对象
     * @param jsonStr JSON字符串
     * @param clazz 目标Java对象类型
     * @param <T> 泛型参数
     * @return 转换后的Java对象，如果转换失败则返回null
     */
    public static <T> T fromJson(String jsonStr, Class<T> clazz) {
        T value = null;
        try {
            value = om.readValue(jsonStr, clazz);
        } catch (Exception e) {
            log.error("fromJson error,jsonStr:" + jsonStr + ",class:" + clazz.getName() + ",exception:"
                    + e.getMessage());
            return null;
        }
        return value;
    }

    /**
     * 将JSON字符串转换为指定TypeReference类型的Java对象
     * @param jsonStr JSON字符串
     * @param valueTypeRef 目标Java对象的TypeReference
     * @param <T> 泛型参数
     * @return 转换后的Java对象，如果转换失败则抛出RuntimeException
     */
    public static <T> T fromJson(String jsonStr, TypeReference<?> valueTypeRef) {
        T value = null;
        try {
            value = (T) om.readValue(jsonStr, valueTypeRef);
        } catch (Exception e) {
            log.error("fromJson error,jsonStr:" + jsonStr + ",class:" + valueTypeRef.getType() + ",exception:"
                    + e.getMessage());
            throw new RuntimeException(e);
        }
        return value;
    }

    /**
     * 将Java对象转换为JSON字符串
     * @param obj 要转换的Java对象
     * @param prettyPrinter 是否使用漂亮的打印格式
     * @return 转换后的JSON字符串，如果转换失败则抛出RuntimeException
     */
    public static String toJson(Object obj, boolean prettyPrinter) {
        if (obj == null) {
            return null;
        }
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator jg = factory.createGenerator(sw);
            if (prettyPrinter) {
                jg.useDefaultPrettyPrinter();
            }
            om.writeValue(jg, obj);
        } catch (IOException e) {
            log.error("toJson error,jsonObj:" + obj.getClass().getName() + ",prettyPrinter:" + prettyPrinter
                    + ",exception:" + e.getMessage());
            throw new RuntimeException(e);
        }
        return sw.toString();
    }

    /**
     * 将Java对象转换为JSON字符串
     * @param object 要转换的Java对象
     * @return 转换后的JSON字符串，如果转换失败则抛出RuntimeException
     */
    public static String toJsonString(Object object) {
        try {
            String valueAsString = om.writeValueAsString(object);
            return valueAsString;
        } catch (Exception e) {
            log.error("toJson error,jsonObj:" + object.getClass().getName() + ",exception:" + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 将Java对象转换为使用默认漂亮打印格式的JSON字符串
     * @param object 要转换的Java对象
     * @return 转换后的JSON字符串，如果转换失败则抛出RuntimeException
     */
    public static String toJsonStringWithDefaultPrettyPrinter(Object object) {
        try {
            String valueAsString = om.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            return valueAsString;
        } catch (Exception e) {
            log.error("toJson error,jsonObj:" + object.getClass().getName() + ",exception:" + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    public static Map<String, Object> toMap(String cacheValue) {
    // 参数校验
    if (cacheValue == null || cacheValue.trim().isEmpty()) {
        return new HashMap<>();
    }

    try {
        // 这里假设cacheValue是JSON格式字符串，使用Jackson进行解析
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(cacheValue, new TypeReference<Map<String, Object>>() {});
    } catch (Exception e) {
        // 处理解析异常，返回空Map或根据业务需求处理
        return new HashMap<>();
    }
}

}
